package com.derbysoft.synxisadapter.dswitch2.translator.impl;

import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.core.GenericRS;
import com.derbysoft.remote.dswitch.hotel.dto.HotelAvailRoomStayDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelMultiAvailRQ;
import com.derbysoft.remote.dswitch.hotel.dto.HotelMultiAvailRS;
import com.derbysoft.remote.dswitch.hotel.dto.HotelRefDTO;
import com.derbysoft.synxisadapter.commons.dto.synxis.OTAHotelAvailRS;
import com.derbysoft.synxisadapter.commons.dto.synxis.RoomStay;
import com.derbysoft.synxisadapter.commons.model.Channel;
import com.derbysoft.synxisadapter.commons.model.Hotel;
import com.derbysoft.synxisadapter.commons.repository.HotelRepository;
import com.derbysoft.synxisadapter.dswitch2.translator.Translator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HotelMultiAvailRSTranslatorImpl extends AbstractRQTranslator
        implements Translator<List<OTAHotelAvailRS>, GenericRS<HotelMultiAvailRS>, GenericRQ<HotelMultiAvailRQ>> {

    private HotelRepository hotelRepository;

    @Override
    public GenericRS<HotelMultiAvailRS> translate(List<OTAHotelAvailRS> otaHotelAvailRSs, GenericRQ<HotelMultiAvailRQ> param) {
        return new GenericRS<HotelMultiAvailRS>(null, createPayload(otaHotelAvailRSs.get(0), param));
    }

    private HotelMultiAvailRS createPayload(OTAHotelAvailRS otaHotelAvailRS, GenericRQ<HotelMultiAvailRQ> rq) {
        HotelMultiAvailRS hotelAvailRS = new HotelMultiAvailRS();
        hotelAvailRS.setHotelAvailRoomStays(createHotelAvailRoomStay(otaHotelAvailRS, rq));
        return hotelAvailRS;
    }

    private List<HotelAvailRoomStayDTO> createHotelAvailRoomStay(OTAHotelAvailRS otaHotelAvailRS, GenericRQ<HotelMultiAvailRQ> rq) {
        List<HotelAvailRoomStayDTO> hotelAvailRoomStayDTOs = new ArrayList<HotelAvailRoomStayDTO>();
        Map<String, HotelAvailRoomStayDTO> maps = new HashMap<String, HotelAvailRoomStayDTO>();
        for (HotelRefDTO hotelRefDTO : rq.getPayload().getHotels()) {
            HotelAvailRoomStayDTO hotelAvailRoomStayDTO = new HotelAvailRoomStayDTO();
            hotelAvailRoomStayDTO.setHotelRef(hotelRefDTO);

            hotelAvailRoomStayDTOs.add(hotelAvailRoomStayDTO);
            maps.put(getHotelId(hotelRefDTO.getCode()), hotelAvailRoomStayDTO);
        }
        Channel channel = findChannel(rq.getHeader().getSource().getUniqueID());
        if (otaHotelAvailRS.getRoomStays() != null) {
            for (RoomStay roomStay : otaHotelAvailRS.getRoomStays().getRoomStay()) {
                HotelAvailRoomStayDTO hotelAvailRoomStayDTO = maps.get(roomStay.getBasicPropertyInfo().getHotelCode());
                hotelAvailRoomStayDTO.setRoomStays(createRoomStayDTOs(rq.getPayload().getStayDateRange(), roomStay, channel, rq.getPayload().getRoomStayCandidates().getNumberOfUnits()));
            }
        }
        return hotelAvailRoomStayDTOs;
    }

    private String getHotelId(String passport) {
        return hotelRepository.findByPassport(passport, Hotel.Status.ENABLED).getId();
    }

    public void setHotelRepository(HotelRepository hotelRepository) {
        this.hotelRepository = hotelRepository;
    }
}
